/*
 * 适用于iview框架的bos百度云上传组件
 * @Author: ljb
 * @Date: 2017-10-12 13:59:50
 * @Last Modified by: kanglin
 * @Last Modified time: 2018-08-23 15:33:34
 */
<style lang="less" rel="stylesheet/less" type="text/less" scoped>

    .v-component-bosupload {
        position: relative;
        display: inline-block;
        background: #fff;
        border: 1px solid #dddee1;
        border-radius: 4px;
        padding: 6px 23px;
        overflow: hidden;
        color: #495060;
        text-decoration: none;
        text-indent: 0;
		line-height: 20px;
		max-width: 288px;
		white-space: nowrap;
		text-overflow: ellipsis;
        input[type='file'] {
            position: absolute;
            font-size: 100px;
            right: 0;
            top: 0;
			opacity: 0;
			max-width: 300px;
        }
        &:hover {
            // background: #AADFFD;
            border-color: #57a3f3;
            color: #57a3f3;
            text-decoration: none;
        }
    }
</style>
<template>
	<a
		href="javascript:;"
		class="v-component-bosupload">
		{{ file_info ||tips || $t('bosupload.selector') }}
		<input
			ref="bos_btn"
			:accept="accept"
			:multiple="multiple"
			:name="name || 'bos-upload'"
			type="file"
			@change="changeInput">
	</a>
</template>

<script>

export default {
	name: 'BosUploader',
	props: {
		bosConfig: {
			type: Object,
			required: true,
		},
		accept: {
			type: String,
			default() {
				return 'video/mp4';
			},
		},
		autoStart: {
			type: Boolean,
			default() {
				return false;
			},
		},
		fileTypeRegExp: {
			type: RegExp,
			default() {
				return /video\/mp4/;
			},
		},
		tips: {
			type: String,
			default() {
				return this.$t('bosupload.selector');
			},
		},
		multiple: {
			type: Boolean,
			default() {
				return false;
			},
		},
		name: {
			type: String,
			default() {
				return '';
			},
		},
	},
	data() {
		return {
			file_info: '',
			bos_uploader: null, // 承接百度云的实例化对象
		};
	},
	watch: {
		bosConfig() {
			if (!this.bos_uploader && JSON.stringify(this.bosConfig) !== '{}') {
				this.initBos();
			}
		},
	},
	mounted() {
		if (!this.bos_uploader && JSON.stringify(this.bosConfig) !== '{}') {
			this.initBos();
		}
	},
	methods: {
		/** 手动上传
		 */
		start() {
			if (this.bos_uploader._files.length === 0) {
				this.$emit('error', new Error('文件不能为空'));
				return;
			}
			this.bos_uploader.start();
		},

		/**
		 * 清空文件队列
		 */
		reset() {
			const $bos_btn = this.$refs.bos_btn;
			$bos_btn.value = '';
			this.bos_uploader._files.splice(0, this.bos_uploader._files.length);
			this.file_info = '';
		},

		/**
         * file模式的input改变时触发的事件
         * @param  {Object} e {事件e}
         * @return {undefined}
         */
		changeInput(e) {
			this.$emit('added', e.target.files);
			if (this.validateFileType(e.target.files[0])) {
				this.file_info = e.target.files[0].name;
			} else {
				this.file_info = '';
			}
		},

		/**
         * 校验文件类型
         * @param  {Object} file {文件对象}
         * @return {Boolean} {true代表校验通过，false代表不通过}
         */
		validateFileType(file) {
			if (!file) {
				this.$Message.error(this.$t('bosupload.no_files_selected')); // 未选择任何文件！
				return;
			}

			const file_type = file.type;

			if (this.fileTypeRegExp.test(file_type)) {
				if (parseFloat(file.size) / 1024 > 102400) {
					this.$Message.error(this.$t('bosupload.size_max', { value: '100m' })); // '所选文件超过100M限制！'

					this.$emit('validate', false);

					return false;
				}

				this.$emit('validate', true);

				return true;
			}

			this.$Message.error(this.$t('bosupload.format_error')); // 所选文件格式不正确！

			this.$emit('validate', false);

			return false;
		},

		/**
         * 获取文件名
         * @param  {Object} file {文件对象}
         * @return {string} {拼接好的文件名}
         */
		getNewFileName(file) {
			const FILE_NAME_MAX_CHAR = 16;

			const file_name = file.name; // xxx.jpeg
			const mime_type = file.type; // eg. "image/jpeg"

			const file_name_arr = file_name.split('.'); // [ 'xxx' , 'jpg' ]
			const extension = mime_type.split('/').pop(); // jpeg

			file_name_arr[0] = file_name_arr[0].slice(0, FILE_NAME_MAX_CHAR); // limit file name length
			file_name_arr.pop(); // [ 'xxx' ]
			file_name_arr.push(`_${(new Date()).getTime()}`); // [ 'xxx' , '_1491231123' ]
			file_name_arr.push(`.${extension}`); // [ 'xxx' , '_123123' , '.jpeg' ]

			return file_name_arr.join('');
		},

		/**
         * 初始化bos
         * @return {undefined}
         */
		initBos() {
			const self = this;
			const $bos_btn = this.$refs.bos_btn;
			/* global baidubce */
			this.bos_uploader = new baidubce.bos.Uploader({
				// 使用id 会导致冲突
				browse_button: $bos_btn, // 需要初始化的<input type="file"/>
				bos_bucket: self.bosConfig.bucket, // 需要上传到的Bucket
				bos_endpoint: self.bosConfig.end_point, // BOS服务器的地址
				bos_task_parallel: 1, // 队列中文件并行上传的个数
				// 通过 JSONP 获取 临时token
				uptoken_url: self.bosConfig.token_url, // 用来进行计算签名的URL，需要支持JSONP
				get_new_uptoken: false, // 如果设置为false，会自动获取到Sts Token，上传的过程中可以减少一些请求
				max_file_size: self.bosConfig.upload_max_size, // 可以选择的最大文件，超过这个值之后，会被忽略掉
				bos_multipart_min_size: self.bosConfig.upload_max_size, // 超过这个值之后，采用分片上传的策略。如果想让所有的文件都采用分片上传，把这个值设置为0即可
				multi_selection: self.multiple, // 是否可以选择多个文件
				init: {
					/**
					 * 初始化完毕之后，调用这个函数
					 */
					PostInit() {
						self.$emit('post-init');
					},
					// 开始上传
					BeforeUpload(_, file) {
						self.$Message.info(self.$t('bosupload.start')); // 开始上传
						self.$emit('on-start', file);
					},

					// 上传完成的回调
					FileUploaded(_, file, info) {
						// const bucket = info.body.bucket;
						const { object, bucket } = info.body;
						const url = `${self.bosConfig.end_point}/${bucket}/${object}`;
						self.$refs.bos_btn.value = '';
						self.file_info = '';
						self.$emit('post', info.body); // { object, bucket}
					},

					// 如果上传的过程中出错了，调用这个函数
					Error(_, error, file) {
						self.$Message.error({
							content: error,
							duration: 5,
							closable: true,
						});
						self.$emit('error', error);
					},

					//  重命名 BOS 存储的文件名称
					Key(_, file) {
						const bos_key = self.bosConfig.prefix + self.getNewFileName(file);

						self.$emit('setKey', bos_key);

						return bos_key;

						// 如果需要重命名 BOS 存储的文件名称，这个函数
						// 返回新的文件名即可
						// 如果这里需要执行异步的操作，可以返回 Promise 对象
						// 如果需要自定义bucket和object，可以返回{bucket: string, key: string}
						// 例如：
						// return new Promise(function (resolve, reject) {
						//   setTimeout(function () {
						//     resolve(file.name);
						//   }, 2000);
						// });
						// return "haha/hehe/cc.jpg";
					},

					// 文件的上传进度
					UploadProgress(_, file, progress) {
						const upload_progress = parseInt(progress.toFixed(2) * 100, 10);
						self.$emit('progress', upload_progress);
					},

					/**
					* 如果需要对加入到队列里面的文件，进行过滤，可以在 返回值需要是一个数组，里面保留需要添加到队列的文件
					*/
					FilesFilter(_, files) {
						if (!self.multiple) {
							// 清空队列已选择的文件
							self.bos_uploader._files.splice(0, self.bos_uploader._files.length);
							return files;
						}
						return files;
					},

					// 当文件被加入到队列里面，调用这个函数
					FilesAdded(_, files) {

					},

				},

			});
		},
	},
};
</script>
